def check_python3(com)
    begin
        `#{com} -c "import sys; print(sys.version_info[0])"`.chomp == '3'
    rescue
        false
    end
end

['python', 'python3'].each {|p|
    if check_python3 p
        PYTHON = p
        break
    end
}
unless defined? PYTHON
    raise "require Python3"
end

DMD = "dmd -v1 -w -release -O -inline" # If does not exists, set to nil.
TXT2TAGS = "txt2tags" # ditto

SEP = File::ALT_SEPARATOR ? '\\' : '/'

# make "sh" verbose by default
if RakeFileUtils.verbose_flag==:default
  verbose(true)
end

require 'rake/clean'
CLEAN.include("*.pyc", "*.pyo", "__pycache__")

desc "build depro"
task :depro do
  if DMD
    sh "#{DMD} -ofdepro#{SEP}depro depro/depro.d depro/bignum.d"
  else
    warn "warning: dmd does not exist."
  end
end
CLEAN.include("depro/*.obj", "depro/*.map", "depro/*.o")
CLOBBER.include("depro/depro", "depro/depro.exe")

desc "build documents"
task :doc => ["doc/tybc.html","doc/epro.html"]
CLOBBER.include("doc/*.html")

rule '.html' => '.t2t' do |t|
  if TXT2TAGS
    sh "#{TXT2TAGS} #{t.source}"
  else
    warn "warning: txt2tags does not exist."
  end
end

desc "make release archive"
task :release => [:depro, :doc] do
  rmtree "release"
  puts "*** build release packgage to release/ ***"
  mkdir_p "release/depro"
  mkdir "release/doc"
  mkdir "release/sample"
  mkdir "release/sample_tape"
  mkdir "release/misc"
  cp "depro/depro", "release/depro" if File.exists?("depro/depro")
  cp "depro/depro.exe", "release/depro" if File.exists?("depro/depro.exe")
  cp "Rakefile", "release", {:preserve => true}
  cp Dir.glob("*.py"), "release", {:preserve => true}
  cp Dir.glob("depro/*.d"), "release/depro", {:preserve => true}
  cp Dir.glob("doc/*"), "release/doc", {:preserve => true}
  cp Dir.glob("sample/*"), "release/sample", {:preserve => true}
  cp Dir.glob("sample_tape/*"), "release/sample_tape", {:preserve => true}
  cp Dir.glob("misc/*"), "release/misc", {:preserve => true}
end
CLOBBER.include("release")

def cmp_txt(f1, f2, checkstep=true)
  open(f1) {|i1|
    open(f2) {|i2|
	  while true
        l1 = i1.gets
	    l2 = i2.gets
	    return true if l1.nil? && l2.nil?
        return true if !checkstep && l1[0] == '*' && l2[0] == '*'
	    return false if l1.nil? || l2.nil? || l1.chomp != l2.chomp
	  end
    }
  }
end

def test(python, dir)
  rmtree dir
  mkdir dir
  puts "** compile all sample **"
  samples=FileList["sample/*.txt"]
  codes=[]
  samples.each {|f|
    c=dir+'/'+File.basename(f,".txt")+'.code'
    sh "#{python} tybc.py #{f} -o #{c}"
    codes << c
  }
  codes.sort!
  sh "#{python} tybc.py -t sample_tape/furui2.txt -o #{dir}/furui2.codet"
  puts "** run all code on eprovm.py **"
  codes.each {|f|
    sh "#{python} eprovm.py #{f} >> #{dir}/py.out"
  }
  sh "echo -100 | #{python} eprovm.py -ts #{dir}/furui2.codet >> #{dir}/py.out"
  puts "** comparing outputs... **"
  unless cmp_txt("misc/test.out", "#{dir}/py.out", false)
    fail "output is differ!!"
  end
  if DMD
    puts "** run all code on depro.exe **"
    codes.each {|f|
      sh "depro#{SEP}depro #{f} >> #{dir}/d.out"
    }
    sh "echo -100 | depro#{SEP}depro -t -s #{dir}/furui2.codet >> #{dir}/d.out"
    puts "** comparing outputs... **"
    unless cmp_txt("#{dir}/py.out", "#{dir}/d.out")
      fail "output is differ!!"
    end
  end
end

desc "run test"
task :test => :depro do
  puts "*** testing ***"
  test(PYTHON, "test")
end
CLEAN.include("test")
